package com.asa.cg;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 模拟的一个线上调优的例子
 * 
 * 这个程序为什么会爆炸的原因
 * ScheduledThreadPoolExecutor是一个延时定时器线程
 * ，新的任务不断的创建，而老的任务的完成需要时间，
 * 这就导致了新的任务创建了，并且在排队，那么排队的对象就会不断创建而不被释放
 * 随着时间的推移，内存中的对象就会越来越多，导致内存占满，触发cg
 * 而这些对象是在排队中的，不是垃圾对象，不会被cg内存回收，
 * 但对象还在不断创建，导致频繁cg，最后内存占满挂掉
 * 
 * 
 * @author Administrator
 *
 */
public class C {
	/**
	 * 	静态类，模拟的用户信息
	 * 	模拟调优问题，设置内存大小一致也算是一种调优方式
	 * 	设置内存大小为200M（最小和最大都是），cmd启动
	 * 	java -Xms200M -Xmx200M -XX:+PrintGC com.asa.cg.C
	 * @author Administrator
	 *
	 */
	private static class CardInfo {
		BigDecimal price = new BigDecimal(0.0);
		String name = "张三";
		int age = 5;
		Date birthdate = new Date();

		public void m() {
		}
	}
	//线程池
	private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50,
			new ThreadPoolExecutor.DiscardOldestPolicy());

	public static void main(String[] args) throws Exception {
		executor.setMaximumPoolSize(50);//设置线程池大小

		for (;;) {
			modelFit();
			Thread.sleep(100);
		}
	}

	private static void modelFit() {
		List<CardInfo> taskList = getAllCardInfo();
		taskList.forEach(info -> {//遍历用户列表，执行方法
			// do something
			executor.scheduleWithFixedDelay(() -> {
				// do sth with info
				info.m();

			}, 2, 3, TimeUnit.SECONDS);
		});
	}

	private static List<CardInfo> getAllCardInfo() {//创建用户信息列表
		List<CardInfo> taskList = new ArrayList<>();

		for (int i = 0; i < 100; i++) {
			CardInfo ci = new CardInfo();
			taskList.add(ci);
		}

		return taskList;
	}
}
